using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.ComponentModel;
using System.Drawing.Printing;
using System.Drawing;
using System.Transactions;
using THSLib;
using THSERP.BaseProvider;
using THSERP.BusinessEntities;
using DevExpress.XtraEditors;

namespace THSERP.Modules.LayBy
{
    public class LayByModule : BaseModuleERP
    {
        #region Constants
        public const String cstLayByStatusNew = "New";  
        public const String cstLayByStatusCancel = "Cancel";
        public const String cstLayByStatusComplete = "Complete";

        public const String cstLayByConfigInitialDeposit = "LayByInitialDeposit";
        public const String cstLayByConfigDueDays = "LayByDueDays";
        #endregion

        private guiCustomersInfo CustomerInfoForm = null;

        public LayByModule()
        {
            Name = "LayBy";
            CurrentModuleEntity = new LayByEntities();
            CurrentModuleEntity.Module = this;
            InitializeModule();

            THSLookupEdit lke = (THSLookupEdit)Controls["fld_lkeFK_ARPriceLevelID"];
            lke.CloseUp += new DevExpress.XtraEditors.Controls.CloseUpEventHandler(ChangePriceLevel);
            lke = (THSLookupEdit)Controls["fld_lkeFK_ARCustomerID"];
            lke.CloseUp += new DevExpress.XtraEditors.Controls.CloseUpEventHandler(ChangeCustomer);
           
            ARSaleOrdersInfo objSaleOrdersInfo = (ARSaleOrdersInfo)CurrentModuleEntity.MainObject;
            //Disable lookupedit if user is an employee
            if (THSApp.CurrentUsersInfo.FK_HREmployeeID > 0)
            {
                objSaleOrdersInfo.FK_HREmployeeID = THSApp.CurrentUsersInfo.FK_HREmployeeID;
                foreach (Control ctrl in Controls.Values)
                    if (!String.IsNullOrEmpty(ctrl.AccessibleName) && ctrl.AccessibleName.Contains("FK_HREmployeeID"))
                    {
                        (ctrl as THSLookupEdit).EditValue = THSApp.CurrentUsersInfo.FK_HREmployeeID;
                        ctrl.Enabled = false;
                    }

                //Show picture of employee
                HREmployeesInfo objHREmployeesInfo = (HREmployeesInfo)new HREmployeesController().GetObjectByID(THSApp.CurrentUsersInfo.FK_HREmployeeID);
                if (objHREmployeesInfo != null)
                {
                    objSaleOrdersInfo.ARSaleOrderEmployeePicture = objHREmployeesInfo.HREmployeePicture;
                    CurrentModuleEntity.UpdateMainObjectBindingSource();
                }
            }
           
            DisplayLabelText(objSaleOrdersInfo);
        }

        public override void ActionEdit()
        {
            String status = String.Empty;
            switch (((ARSaleOrdersInfo)CurrentModuleEntity.MainObject).ARSaleOrderStatus)
            {
                case LayByModule.cstLayByStatusCancel:
                    status = "canceled";
                    break;
                case LayByModule.cstLayByStatusComplete:
                    status = "completed";
                    break;
            }
            if (!String.IsNullOrEmpty(status))
            {
                MessageBox.Show(String.Format("The lay-by has been {0} and can not modified", status), "#Message#", MessageBoxButtons.OK, MessageBoxIcon.Information);
                DevExpress.XtraBars.BarButtonItem barbtnEdit = ParentScreen.GetToolbarButton(BaseToolbar.ToolbarButtonEdit);
                if (barbtnEdit != null)
                    barbtnEdit.Down = false;
                CurrentModuleEntity.SetPropertyChangeEventLock(false);
                return;
            }

            base.ActionEdit();
        }

        public override void ActionNew()
        {
            base.ActionNew();

            LayByEntities entity = (LayByEntities)CurrentModuleEntity;
            ARSaleOrdersInfo objSaleOrdersInfo = (ARSaleOrdersInfo)entity.MainObject;
            if (THSApp.CurrentUsersInfo.FK_HREmployeeID > 0)
            {
                objSaleOrdersInfo.FK_HREmployeeID = THSApp.CurrentUsersInfo.FK_HREmployeeID;
                //Show picture of employee
                HREmployeesInfo objHREmployeesInfo = (HREmployeesInfo)new HREmployeesController().GetObjectByID(objSaleOrdersInfo.FK_HREmployeeID);
                if (objHREmployeesInfo != null)
                {
                    ((ARSaleOrdersInfo)CurrentModuleEntity.MainObject).ARSaleOrderEmployeePicture = objHREmployeesInfo.HREmployeePicture;
                    CurrentModuleEntity.UpdateMainObjectBindingSource();
                }
            }

            objSaleOrdersInfo.ARSaleOrderDate = DateTime.Now;
            objSaleOrdersInfo.ARSaleOrderDeliveryDate = THSUtil.GetYearEndDate();
            if (THSApp.CurrentCompanyInfo != null)
            {
                objSaleOrdersInfo.FK_ICStockID = THSApp.CurrentCompanyInfo.FK_ICStockID;
            }
            objSaleOrdersInfo.FK_ARPriceLevelID = 1;
            objSaleOrdersInfo.ARSaleOrderTypeCombo = SaleOrder.SaleOrderModule.cstSaleOrderTypeLayBy;
            objSaleOrdersInfo.ARSaleOrderPromotionDiscountCheck = false;
            objSaleOrdersInfo.ARSaleOrderCustomerDiscountCheck = false;
            CurrentModuleEntity.UpdateMainObjectBindingSource();
            DisplayLabelText(objSaleOrdersInfo);
        }

        public override int ActionSave()
        {
            if (!IsInvalidInventory())
            {
                int objectID = base.ActionSave();
                if (objectID > 0)
                    TakePayment();
                return objectID;
            }
            return 0;
        }

        public override void SetDefaultValuesFromCustomer()
        {
            
            LayByEntities entity = (LayByEntities)CurrentModuleEntity;
            ARSaleOrdersInfo objSaleOrdersInfo = (ARSaleOrdersInfo)entity.MainObject;

            int customerID = Convert.ToInt32(THSDbUtil.GetPropertyValue(entity.MainObject, "FK_ARCustomerID"));
            ARCustomersController objCustomersController = new ARCustomersController();
            ARCustomersInfo objCustomersInfo = (ARCustomersInfo)objCustomersController.GetObjectByID(customerID);
            if (objCustomersInfo != null)
            {
                //Set total amount, discount for the customer_Hieu.nguyen_31/3/2010
                ARPriceLevelsController objPriceLevelsController = new ARPriceLevelsController();
                ARPriceLevelsInfo objPriceLevelsInfo = (ARPriceLevelsInfo)objPriceLevelsController.GetObjectByID(objCustomersInfo.FK_ARPriceLevelID);
                objCustomersInfo.ARCustomerPriceLevelName = objPriceLevelsInfo.ARPriceLevelName;
                objCustomersInfo.ARCustomerTotalPurchase = objCustomersController.GetTotalInvoiceAmount(objCustomersInfo.ARCustomerID);
                objCustomersInfo.ARCustomerTotalDiscount = objCustomersController.GetTotalInvoiceDiscount(objCustomersInfo.ARCustomerID);
                objCustomersInfo.ARCustomerTotalRefund = objCustomersController.GetTotalInvoiceRefund(objCustomersInfo.ARCustomerID);

                if (!Toolbar.IsNullOrNoneAction())
                {
                    if (objCustomersInfo.FK_ARPriceLevelID > 0 && objCustomersInfo.FK_ARPriceLevelID != objSaleOrdersInfo.FK_ARPriceLevelID)
                        ShowCustomerInfo(objCustomersInfo, true);
                    else
                        ShowCustomerInfo(objCustomersInfo, false);
                    ((LayByEntities)CurrentModuleEntity).SetDefaultValuesFromCustomer(objCustomersInfo, CustomerInfoForm.fld_chkApplyPriceLevel.Checked);
                }
                else
                    ShowCustomerInfo(objCustomersInfo, false);
            }
        }

        public void ShowCustomerInfo(ARCustomersInfo objCustomersInfo, bool showPriceLevelPanel)
        {
            if (CustomerInfoForm == null)
            {
                CustomerInfoForm = new guiCustomersInfo();
                CustomerInfoForm.Module = this;
            }
            CustomerInfoForm.DisplayCustomerInfo(objCustomersInfo);
            CustomerInfoForm.fld_chkApplyPriceLevel.Checked = false;
            CustomerInfoForm.fld_pnlPriceLevel.Visible = showPriceLevelPanel;
            CustomerInfoForm.ShowDialog();
        }

        public void AddItemToSaleOrderItemsList()
        {
            LayByEntities entity = (LayByEntities)CurrentModuleEntity;
            ARSaleOrderItemsInfo objSaleOrderItemsInfo = (ARSaleOrderItemsInfo)entity.ModuleObjects[SaleOrder.SaleOrderEntities.strARSaleOrderItemsObjectName];
            //Check Inventory_Hieu.nguyen_21/04/2010
            if (!entity.IsInvalidInventory(objSaleOrderItemsInfo, TransactionUtil.cstInventoryShipment))
            {
                if (objSaleOrderItemsInfo.FK_ICProductID > 0)
                {
                    objSaleOrderItemsInfo.ARSaleOrderItemProductQtyOld = objSaleOrderItemsInfo.ARSaleOrderItemProductQty;
                    entity.SetProductPriceByProductUnitPrice();
                    entity.ARSaleOrderItemsList.AddObjectToList();
                    entity.UpdateTotalAmount();
                }
            }
        }

        public void ChangeItemFromSaleOrderItemsList()
        {
            LayByEntities entity = (LayByEntities)CurrentModuleEntity;
            ARSaleOrderItemsInfo objSaleOrderItemsInfo = (ARSaleOrderItemsInfo)entity.ModuleObjects[SaleOrder.SaleOrderEntities.strARSaleOrderItemsObjectName];
            //Check Inventory_Hieu.nguyen_21/04/2010
            if (!entity.IsInvalidInventory(objSaleOrderItemsInfo, TransactionUtil.cstInventoryShipment))
            {
                objSaleOrderItemsInfo.ARSaleOrderItemProductQtyOld = objSaleOrderItemsInfo.ARSaleOrderItemProductQty;
                entity.SetProductPriceByProductUnitPrice();
                entity.ARSaleOrderItemsList.ChangeObjectFromList();
                entity.UpdateTotalAmount();
            }
            else
            {
                objSaleOrderItemsInfo.ARSaleOrderItemProductQty = objSaleOrderItemsInfo.ARSaleOrderItemProductQtyOld;
                entity.ARSaleOrderItemsList.ChangeObjectFromList();
            }
        }

        public void DeleteItemFromSaleOrderItemsList()
        {
            LayByEntities entity = (LayByEntities)CurrentModuleEntity;
            entity.ARSaleOrderItemsList.RemoveSelectedRowObjectFromList();
            entity.UpdateTotalAmount();
        }

        public void ChangeCustomer(object sender, DevExpress.XtraEditors.Controls.CloseUpEventArgs e)
        {
            if (!Toolbar.IsNullOrNoneAction())
            {
                THSLookupEdit lke = (THSLookupEdit)sender;
                if (e.Value != lke.OldEditValue)
                {
                    LayByEntities entity = (LayByEntities)CurrentModuleEntity;
                    ((ARSaleOrdersInfo)entity.MainObject).FK_ARCustomerID = Convert.ToInt32(e.Value);
                    SetDefaultValuesFromCustomer();
                }
            }
        }

        public void ChangePriceLevel(object sender, DevExpress.XtraEditors.Controls.CloseUpEventArgs e)
        {
            if (!Toolbar.IsNullOrNoneAction())
            {
                THSLookupEdit lke = (THSLookupEdit)sender;
                if (e.Value != lke.OldEditValue)
                {
                    LayByEntities entity = (LayByEntities)CurrentModuleEntity;
                    ((ARSaleOrdersInfo)entity.MainObject).FK_ARPriceLevelID = Convert.ToInt32(e.Value);
                    if (entity.ARSaleOrderItemsList.Count > 0)
                    {
                        if (MessageBox.Show("Do you want to update new price level to the listed items?", "#Message#", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                        {
                            foreach (SaleOrderItemsEntity entItem in entity.ARSaleOrderItemsList)
                                entity.SetProductPrice(entItem, SaleOrder.SaleOrderEntities.strARSaleOrderItemsObjectName);
                            entity.ARSaleOrderItemsList.GridControl.RefreshDataSource();
                            entity.UpdateTotalAmount();
                        }
                    }
                }
            }
        }

        public void ChangeDiscountOption(object sender)
        {
            LayByEntities entity = (LayByEntities)CurrentModuleEntity;
            DevExpress.XtraEditors.CheckEdit chk = (DevExpress.XtraEditors.CheckEdit)sender;
            if (chk.Name.Contains("ARSaleOrderPromotionDiscountCheck"))
                ((ARSaleOrdersInfo)entity.MainObject).ARSaleOrderPromotionDiscountCheck = !chk.Checked;
            else
                ((ARSaleOrdersInfo)entity.MainObject).ARSaleOrderCustomerDiscountCheck = !chk.Checked;
            if (entity.ARSaleOrderItemsList.Count > 0)
            {
                foreach (SaleOrderItemsEntity entItem in entity.ARSaleOrderItemsList)
                    entity.SetProductPriceByProductUnitPrice(entItem, SaleOrder.SaleOrderEntities.strARSaleOrderItemsObjectName);
                entity.ARSaleOrderItemsList.GridControl.RefreshDataSource();
                entity.UpdateTotalAmount();
            }
            if (chk.Name.Contains("ARSaleOrderPromotionDiscountCheck"))
                ((ARSaleOrdersInfo)entity.MainObject).ARSaleOrderPromotionDiscountCheck = !chk.Checked;
            else
                ((ARSaleOrdersInfo)entity.MainObject).ARSaleOrderCustomerDiscountCheck = !chk.Checked;
        }

        public void ChangeDiscountPercent()
        {
            ((LayByEntities)CurrentModuleEntity).UpdateTotalAmount();
        }

        public void ChangeDiscountAmount()
        {
            LayByEntities entity = (LayByEntities)CurrentModuleEntity;
            ARSaleOrdersInfo objSaleOrdersInfo = (ARSaleOrdersInfo)entity.MainObject;
            if (objSaleOrdersInfo.ARSaleOrderSubTotalAmount > 0)
                objSaleOrdersInfo.ARSaleOrderDiscountPerCent = objSaleOrdersInfo.ARSaleOrderDiscountFix / objSaleOrdersInfo.ARSaleOrderSubTotalAmount * 100;
            entity.UpdateTotalAmount();
        }

        public void TakePayment()
        {
            if (Toolbar.IsNullOrNoneAction() && Toolbar.CurrentObjectID > 0)
            {
                ARSaleOrdersController objSaleOrdersController = new ARSaleOrdersController();
                Invalidate(Toolbar.CurrentObjectID);
                ARSaleOrdersInfo objSaleOrdersInfo = (ARSaleOrdersInfo)CurrentModuleEntity.MainObject;
                if (objSaleOrdersInfo.ARSaleOrderStatus == LayByModule.cstLayByStatusCancel)
                {
                    MessageBox.Show("Can not take payment on canceled lay-by", "#Message#", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
                if (objSaleOrdersInfo.ARSaleOrderStatus == LayByModule.cstLayByStatusComplete)
                {
                    MessageBox.Show("Can not take payment on complete lay-by", "#Message#", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
                if (objSaleOrdersInfo.ARSaleOrderBalanceDue > 0)
                {
                    guiLayByPayment guiLayByPayment = new guiLayByPayment(objSaleOrdersInfo.ARSaleOrderBalanceDue, objSaleOrdersInfo.ARSaleOrderDepositBalance);
                    if (guiLayByPayment.ShowDialog() == DialogResult.OK)
                    {
                        double paymentAmount = Convert.ToDouble(guiLayByPayment.Tag);
                        if (paymentAmount > 0)
                        {
                            double balanceDue = objSaleOrdersInfo.ARSaleOrderBalanceDue;
                            if (paymentAmount < balanceDue)
                                balanceDue = paymentAmount;

                            guiPaymentDetails guiPaymentDetails = new guiPaymentDetails(this, ADConfigValueUtility.cstOpenDocumentTypeLayBy, balanceDue, paymentAmount);
                            if (guiPaymentDetails.ShowDialog() == DialogResult.OK)
                            {
                                CurrentModuleEntity.SetPropertyChangeEventLock(false);
                                LayByEntities entity = (LayByEntities)CurrentModuleEntity;
                                entity.ARDocumentPaymentDetailsList = guiPaymentDetails.PaymentList;
                                int invoiceID = entity.TakePayment(balanceDue);

                                bool firstPayment = false;
                                if (objSaleOrdersInfo.ARSaleOrderDepositBalance == 0)
                                    firstPayment = true;

                                objSaleOrdersInfo.ARSaleOrderDepositBalance += Math.Min(paymentAmount, objSaleOrdersInfo.ARSaleOrderBalanceDue);
                                objSaleOrdersInfo.ARSaleOrderBalanceDue -= Math.Min(paymentAmount, objSaleOrdersInfo.ARSaleOrderBalanceDue);
                                objSaleOrdersController.UpdateObject(objSaleOrdersInfo);
                                entity.UpdateMainObjectBindingSource();
                                CurrentModuleEntity.SetPropertyChangeEventLock(true);

                                if (guiPaymentDetails.Tag.ToString() == "SavePrint")
                                {
                                    //If the payment is first one, print lay-by
                                    if (firstPayment)
                                        PrintLayBy();
                                    else
                                    {
                                        //Print Layby payment_13/04/2010
                                        PrintLayByPayment(invoiceID);
                                    }
                                }
                                
                                if (objSaleOrdersInfo.ARSaleOrderBalanceDue == 0)
                                {
                                    ActionComplete();
                                }
                            }
                        }
                    }
                }
                else
                    ActionComplete();
            }
        }

        public override bool ActionComplete()
        {
            if (Toolbar.CurrentObjectID > 0)
            {
                if (MessageBox.Show("The balance due has been paid completely. Do you want to complete the lay-by?", "#Message#", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew))
                    {
                        try
                        {
                            bool isComplete = CurrentModuleEntity.CompleteTransaction();
                            scope.Complete();
                            MessageBox.Show("Complete successfully", "#Message#", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            return true;
                        }
                        catch (Exception)
                        {
                            scope.Dispose();
                        }
                    }
                }
            }
            return false;
        }

        public void CancelLayBy()
        {
            if (Toolbar.IsNullOrNoneAction() && Toolbar.CurrentObjectID > 0)
            {
                Invalidate(Toolbar.CurrentObjectID);
                ARSaleOrdersInfo objSaleOrdersInfo = (ARSaleOrdersInfo)CurrentModuleEntity.MainObject;
                if (objSaleOrdersInfo.ARSaleOrderStatus == LayByModule.cstLayByStatusCancel)
                {
                    MessageBox.Show("The lay-by has been canceled and can not cancel again", "#Message#", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
                if (objSaleOrdersInfo.ARSaleOrderStatus == LayByModule.cstLayByStatusComplete)
                {
                    MessageBox.Show("The lay-by has been completed and can not cancel", "#Message#", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
                if (MessageBox.Show("Do you want to cancel this lay-by?", "#Message#", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    ((LayByEntities)CurrentModuleEntity).CancelLayBy();
                }
            }
        }

        public override void Invalidate(int iObjectID)
        {
            base.Invalidate(iObjectID);

            //Show picture
            LayByEntities entity = (LayByEntities)CurrentModuleEntity;
            ARSaleOrdersInfo objARSaleOrdersInfo = (ARSaleOrdersInfo)entity.MainObject;
            HREmployeesInfo objHREmployeesInfo = (HREmployeesInfo)new HREmployeesController().GetObjectByID(objARSaleOrdersInfo.FK_HREmployeeID);
            if (objHREmployeesInfo != null)
            {
                ((ARSaleOrdersInfo)CurrentModuleEntity.MainObject).ARSaleOrderEmployeePicture = objHREmployeesInfo.HREmployeePicture;
                CurrentModuleEntity.UpdateMainObjectBindingSource();
            }
            DisplayLabelText(objARSaleOrdersInfo);
        }

        /// <summary>
        /// Print layby
        /// </summary>
        /// <remarks>Hieu.nguyen_9/4/2010</remarks>
        public void PrintLayBy()
        {
            if (Toolbar.CurrentObjectID > 0)
            {
                String strReportFileName = System.Windows.Forms.Application.StartupPath + "\\Reports\\" + this.Name + "\\" + "Layby.rpt";
                ReportHelper.FileName = strReportFileName;
                Hashtable reportParams = new Hashtable();
                reportParams.Add("prARSaleOrderID", Toolbar.CurrentObjectID);
                reportParams.Add("prBRBranchID", THSApp.CurrentCompanyInfo.FK_BRBranchID);
                ReportHelper.DisplayReport(reportParams);
                ReportHelper.ReportDoc.PrintToPrinter(1, false, 1, 1);
            }
        }

        public void PrintLayByPayment(int invoiceID)
        {
            if (Toolbar.CurrentObjectID > 0)
            {
                String strReportFileName = System.Windows.Forms.Application.StartupPath + "\\Reports\\" + this.Name + "\\" + "LaybyPayment.rpt";
                ReportHelper.FileName = strReportFileName;
                Hashtable reportParams = new Hashtable();
                reportParams.Add("prARSaleOrderID", Toolbar.CurrentObjectID);
                reportParams.Add("prBRBranchID", THSApp.CurrentCompanyInfo.FK_BRBranchID);
                reportParams.Add("prARInvoiceID", invoiceID);
                ReportHelper.DisplayReport(reportParams);
                ReportHelper.ReportDoc.PrintToPrinter(1, false, 1, 1);
            }
        }

        /// <summary>
        /// validated staff
        /// </summary>
        ///<remarks>HieuNH_15/04/2010</remarks>
        ///
        public void Staff_Validated(object sender, EventArgs e)
        {
            THSLookupEdit lke = (THSLookupEdit)sender;
            if (lke != null && lke.EditValue != lke.OldEditValue)
            {
                HREmployeesInfo objHREmployeesInfo = (HREmployeesInfo)new HREmployeesController().GetObjectByID(Convert.ToInt32(lke.EditValue));
                if (objHREmployeesInfo != null)
                {
                    ((ARSaleOrdersInfo)CurrentModuleEntity.MainObject).ARSaleOrderEmployeePicture = objHREmployeesInfo.HREmployeePicture;
                    CurrentModuleEntity.UpdateMainObjectBindingSource();
                }
            }
        }

        public void EditCustomer()
        {
            ARSaleOrdersInfo objARSaleOrdersInfo = (ARSaleOrdersInfo)CurrentModuleEntity.MainObject;
            Modules.Customer.CustomerModule customerModule = (Modules.Customer.CustomerModule)ParentScreen.ShowModule("Customer");
            for (int i = 0; i < customerModule.Toolbar.ObjectCollection.Tables[0].Rows.Count; i++)
                if (objARSaleOrdersInfo.FK_ARCustomerID == Convert.ToInt32(customerModule.Toolbar.ObjectCollection.Tables[0].Rows[i]["ARCustomerID"]))
                {
                    customerModule.Toolbar.CurrentIndex = i;
                    customerModule.FocusRowOfGridSearchResultByToolbarCurrentIndex();
                    customerModule.Invalidate(objARSaleOrdersInfo.FK_ARCustomerID);
                    customerModule.ActionEdit();
                    return;
                }
        }
    }
}
